(define random_points
  (lambda (n)
    (let
	((aux (lambda (from to)
		(if (= from to)
		    '()
		    (cons (vector (random-integer 600) (random-integer 600)) (aux (+ from 1) to))))))
      (if (<= n 3)
	  (error "random_points: Bad argument")
	  (aux 0 n)))))

(define cross-product
  (lambda (v1 v2)
    (- (* (vector-ref v1 1) (vector-ref v2 2)) (* (vector-ref v2 1) (vector-ref v1 2)))))

(define sort
  (lambda (ls)
    (let ((split (lambda (ls)
		   (letrec ((split-h (lambda (ls ls1 ls2)
				       (cond
					((or (null? ls) (null? (cdr ls))) (vector (reverse ls2) ls1))
					(else (split-h (cddr ls) (cdr ls1) (cons (car ls1) ls2)))))))
		     (split-h ls ls '()))))
	  (merge (lambda (ls1 ls2)
		   (cond
		    ((null? ls1) ls2)
		    ((null? ls2) ls1)
		    ((< (vector-ref (car ls1) 1) (vector-ref (car ls2) 1)) (cons (car ls1) (merge (cdr ls1) ls2)))
		    (else (cons (car ls2) (merge ls1 (cdr ls2))))))))
      (cond
       ((null? ls) ls)
       ((null? (cdr ls)) ls)
       (else (let ((splits (split ls)))
	       (merge (sort (vector-ref splits 1)) (sort (vector-ref splits 2)))))))))

(define json-points
  (lambda (points envelop)
    (let ((aux (lambda(list)
		 (cond
		    ((null? list) "")
		    ((pair? list) (if (null? cdr)
				      (string-append "{" (number->string (vector-ref (car list) 1)) "," (number->string (vector-ref (car list) 2)) "}")
				      (string-append "{" (number->string (vector-ref (car list) 1)) "," (number->string (vector-ref (car list) 2)) "}," (string #\newline) (aux (cdr list)))))
		    (else (error "json-points: Bad argument"))))))
      (string-append "{" (string #\newline) "'points': [" (aux points) (string #\newline) "]," (string #\newline) "'envelop': [" (aux envelop) (string #\newline) "]" (string #\newline) "}"))))